#pragma once
#ifndef _STORAGE_H_
#define _STORAGE_H_

#include <vector>
#include <exception>
#include "FloatingTask.h"
#include "DeadlineTask.h"
#include "TimedTask.h"
#include "CommonConstant.h"

using namespace std;

/* Class name: Storage
 *
 * This class models a list of task used in TaskLine. It uses the vector library to 
 * manipulate the task within the list. It contains basic CREATE/READ/UPDATE/DELETE(CRUD)
 * operation for the list to work with.
 *
 * @author A0096955J
 */
class Storage{
public:
	// CRUD operations on task list
	string addTask(FloatingTask*);
	string retrieveTaskStringInfo(int);
	FloatingTask* retrieveTask(int);
	string updateTask(int, FloatingTask*);
	string deleteTask(int);
	string insertTask(int, FloatingTask*);

	enum updateType{
		UPDATE_TITLE, UPDATE_DESCRIPTION, UPDATE_LOCATION, UPDATE_PERSON,
		UPDATE_PRIORITY, UPDATE_STATUS, UPDATE_START_TIME, UPDATE_END_TIME, UPDATE_START_DATE,
		UPDATE_END_DATE
	};

	// other task list methods
	vector <FloatingTask*> getTaskList(); // returns a vector of Task
	int size(); // returns size of task list
	char retrieveTaskType(int); //	 returns f for floating tasks
								//			 d for deadline task
								//			 t for timed tasks
								//           X for out of range	

	// singleton implementation
	static Storage* getInstance();

	// destructor
	~Storage(void);
private:
	static Storage *theOnlyStorage;
	vector <FloatingTask*> taskList;
	string message;
	Storage(void);
	
	//internal methods
	void checkRange(int);
	string errorMessageOutOfRange(string);

};

/* Class Name: OutOfRange
 * 
 * This class is error handling exception class to handle case where by user tries to 
 * access range out of the task list.
 */
class OutOfRange: public exception{
	public:
		OutOfRange(void);
		~OutOfRange(void);
		const string returnString() const;
		const char returnCharacter() const;
		FloatingTask* returnNullPointer() const;
};

#endif